package com.cz.tcpclientmaster;

import android.os.Handler;
import android.os.Message;

import com.cz.tcpclientmaster.util.LogUtil;
import com.cz.tcpclientmaster.util.NetWorkUtil;

/**
 * @author 陈章
 * create at 2021/1/22 15:22
 * desc:在框架层面重新建立连接
 * 一.连接断开的可能原因
 * 1）服务端主动断开客户端
 * 2）服务端停止服务
 * 3）服务端断网
 * 4）服务端异常(如进程被杀死)
 * 4）客户端断网
 * 5）客户端异常
 * 6）客户端主动断开
 *
 * 二.哪些情况需要重连
 * 首先，服务端是可连的,即服务端服务已经开启，且网络正常。
 *
 * 对于客户端，对于非主动断开的情况，一般要做重连处理。
 * 1）服务端主动正常业务断开，不需要重连。这个只能在业务层协议里处理。
 * 2）客户端检测到非正常断开连接，会尝试重新连接服务端，在自身网络正常的情况下才真正去建立连接。
 * 一次建立连接的过程未结束，不会重新去建立连接。
 */
class ReconnectController {
    private static final String TAG = "ReconnectController";
    /**
     * 需要调用SocketClient的连接方法
     */
    private TcpSocketClient socketClient;

    /**
     * 复用SocketClient的Handler，进行子线程操作。
     */
    private Handler childHandler;
    private final int MSG_TYPE_START_RECONNECT = 100;

    void handleMessage(Message msg){
      switch (msg.what){
          case MSG_TYPE_START_RECONNECT:
              reconnectPrivate();
              break;
      }
    }

    ReconnectController(TcpSocketClient socketClient, Handler childHandler) {
        this.socketClient = socketClient;
        this.childHandler = childHandler;
    }

    /**
     * 供{@link TcpSocketClient}重连的接口
     */
    void reconnect(){
        //这里再判断，是为了可能及时同步socket client的设置。
        if(socketClient.isAutoReconnect()){
            childHandler.obtainMessage(MSG_TYPE_START_RECONNECT).sendToTarget();
        }
    }

    /**
     * 关闭可能存在的重连请求，避免{@link TcpSocketClient#connect(String, int)}方法执行时冲突。
     */
    void stopRunningTask(){
        childHandler.removeCallbacksAndMessages(MSG_TYPE_START_RECONNECT);
    }

    private void reconnectPrivate(){
        LogUtil.e(TAG,"连接异常断开,客户端重新建立连接");
        //判断网络状况
        if(NetWorkUtil.isNetWorkEnable(socketClient.getContext())){
            socketClient.reconnect();
        }else{
            LogUtil.e("没有检测到网络");
            childHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    reconnect();
                }
            },socketClient.getAutoReconnectRateTimeMillis());
        }
    }
}
